package 创建型模式

/**
 * 将一个复杂对象的构建与它的表示分离，使得同样的构建过程可以创建不同的表示
 */

class HtmlBuilder {
    private val headerBuilder = HeaderBuilder()
    val hrBuilder = HrBuilder()
    val quoteBuilder = QuoteBuilder()
    val paragraphBuilder = ParagraphBuilder()

    fun toHtml(markdown: String): String {
        val buffer = StringBuilder()
        markdown.lines().forEach { line ->
            if (line.startsWith("#")) {
                buffer.append(headerBuilder.buildingHeading(line)).append("\n")
            } else {

            }
        }
        return buffer.toString()
    }
}

/**
 * Builder模式是为了创建一个复杂的对象，需要多个步骤完成创建，或者需要多个零件组装的场景，且创建过程中可以灵活调用不同的步骤或组件
 */

class ParagraphBuilder {

}

class QuoteBuilder {

}

class HrBuilder {

}

class HeaderBuilder {
    fun buildingHeading(line: String): String {
        var n = 0
        while (line[0] == '#') {
            n++
        }
        return "<h$n>${line.substring(n)}</h$n>"
    }
}


class URLBuilder2 {
    var domain = ""
    var schema = ""
    var query = mapOf<String, String>()

    companion object {
        fun builder(): URLBuilder2 {
            return URLBuilder2()
        }
    }

    fun build(): String {
        return StringBuilder().run {
            if (schema.isNotEmpty()) append(schema).append("//")
            if (domain.isNotEmpty()) append(domain).append("?")
            if (query.isNotEmpty()) {
                query.forEach { (key, value) ->
                    append("$key=$value").append("&")
                }
            }
            //移除最后一个多余的&
            removeSuffix("&")
            toString()
        }
    }

}


class URI(
    private val domain: String,
    private val schema: String,
    private val query: MutableMap<String, String>
) {
    override fun toString() = StringBuilder().run {
        if (schema.isNotEmpty()) append(schema).append("//")
        if (domain.isNotEmpty()) append(domain).append("?")
        if (query.isNotEmpty()) {
            query.forEach { (key, value) ->
                append("$key=$value").append("&")
            }
        }
        //移除最后一个多余的&
        removeSuffix("&")
        toString()
    }
}

interface URIBuilder {
    fun domain(domain: String): URIBuilder
    fun schema(schema: String): URIBuilder

    fun query(query: MutableMap<String, String>): URIBuilder

    fun build(): URI

    companion object {
        fun createBuilder(): URIBuilder {
            return impl
        }

        private val impl = URIBuilderImpl()
    }
}

class URIBuilderImpl : URIBuilder {
    private var domain = ""
    private var schema = ""
    private var query = mutableMapOf<String, String>()
    override fun domain(domain: String): URIBuilderImpl {
        this.domain = domain
        return this
    }

    override fun schema(schema: String): URIBuilder {
        this.schema = schema
        return this
    }

    override fun query(query: MutableMap<String, String>): URIBuilderImpl {
        this.query = query
        return this
    }

    override fun build(): URI {
        return URI(this.domain, this.schema, this.query)
    }
}

fun main() {
    val uri = URIBuilder.createBuilder()
        .schema("https:")
        .domain("www.liaoxuefeng.com")
        .query(mutableMapOf("a" to "123", "q" to "K&R"))
        .build()
    println(uri)
}